package com.xl.bigdata.ai.sa;

import cn.hutool.core.util.NumberUtil;
import com.hankcs.hanlp.classification.classifiers.IClassifier;
import com.hankcs.hanlp.classification.classifiers.NaiveBayesClassifier;
import com.hankcs.hanlp.classification.models.NaiveBayesModel;
import com.hankcs.hanlp.corpus.io.IOUtil;
import com.xl.bigdata.bean.SentimentAnalysisBean;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.math.BigDecimal;
import java.util.Map;
import java.util.Map.Entry;

public class SentimentAnalysisOne
{
    public static volatile IClassifier classifier;
    public static volatile SentimentAnalysisOne sentimentAnalysisOne;

    public static void initModel(String modelPath)
    {
        if (classifier == null) {
            synchronized (SentimentAnalysisOne.class) {
                NaiveBayesModel model = (NaiveBayesModel)IOUtil.readObjectFrom(modelPath);
                classifier = new NaiveBayesClassifier(model);
            }
        }
    }

    public static SentimentAnalysisOne getInstance()
    {
        if (sentimentAnalysisOne == null) {
            synchronized (SentimentAnalysisOne.class) {
                sentimentAnalysisOne = new SentimentAnalysisOne();
            }
        }

        return sentimentAnalysisOne;
    }

    public SentimentAnalysisBean predict(String text)
    {
        SentimentAnalysisBean sentimentAnalysisBean = new SentimentAnalysisBean();

        Map<String, Double> predict = classifier.predict(text);
        double max = (-1.0D / 0.0D);
        String best = null;
        for (Entry<String, Double>  entry : predict.entrySet()) {
            Double score = (Double)entry.getValue();
            if (score.doubleValue() > max) {
                max = score.doubleValue();
                best = (String)entry.getKey();
            }
        }

        BigDecimal round = NumberUtil.round(max, 1);
        max = round.doubleValue();

        if ((Double.doubleToLongBits(max) >= Double.doubleToLongBits(0.4D)) &&
                (Double.doubleToLongBits(max) <=
                        Double.doubleToLongBits(0.6D))) {
            best = "中性";
        }

        System.out.printf("《%s》 情感极性是 【%s】 分值【%s】\n", new Object[] { text, best, Double.valueOf(max) });

        sentimentAnalysisBean.setInputCon(text);
        sentimentAnalysisBean.setOutputCon(best);
        sentimentAnalysisBean.setScore(max);

        return sentimentAnalysisBean;
    }
    private static NaiveBayesModel trainOrLoadModel() throws IOException
    {
        String MODEL_PATH = "E://lexin/sourceCode/BoyBD/data/test/v1sentimentAnalysis-model.ser";

        String CORPUS_FOLDER ="E://lexin/sourceCode/BoyBD/data/test/情感分析数据V1";

        NaiveBayesModel model = (NaiveBayesModel) IOUtil.readObjectFrom(MODEL_PATH);
        if (model != null) {
            return model;
        }

        File corpusFolder = new File(CORPUS_FOLDER);
        if (!corpusFolder.exists() || !corpusFolder.isDirectory())
        {
            System.err.println("没有文本分类语料，请阅读IClassifier.train(java.lang.String)中定义的语料格式与语料下载：" +
                    "https://github.com/hankcs/HanLP/wiki/%E6%96%87%E6%9C%AC%E5%88%86%E7%B1%BB%E4%B8%8E%E6%83%85%E6%84%9F%E5%88%86%E6%9E%90");
            System.exit(1);
        }

        IClassifier classifier = new NaiveBayesClassifier(); // 创建分类器，更高级的功能请参考IClassifier的接口定义
        classifier.train(CORPUS_FOLDER);                     // 训练后的模型支持持久化，下次就不必训练了
        model = (NaiveBayesModel) classifier.getModel();
        IOUtil.saveObjectTo(model, MODEL_PATH);
        return model;
    }
    public static void main(String[] args)
    {

//        try {
//            trainOrLoadModel();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }

        initModel("E://lexin/sourceCode/BoyBD/data/test/v1sentimentAnalysis-model.ser");
        SentimentAnalysisBean predict = new SentimentAnalysisOne().predict("感谢您的咨询，祝您新年快乐，阖家幸福，再见。");
        System.out.println(predict.toString());
    }
}